﻿package com.wly.box2d
{
	import com.wly.interval.IntervalCallBack;
	import com.wly.ui.common.GlobalInfo;
	
	import flash.display.Sprite;
	
	import Box2D.Collision.b2WorldManifold;
	import Box2D.Collision.Shapes.b2PolygonShape;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2DebugDraw;
	import Box2D.Dynamics.b2FixtureDef;
	import Box2D.Dynamics.b2Island;
	import Box2D.Dynamics.b2World;
	
	import flashx.textLayout.formats.BlockProgression;

	public class Box2WorldManager
	{
		private var _b2World:b2World;
		private var _b2ItemArr:Array;
		private var _interval:IntervalCallBack;
		
		public function Box2WorldManager()
		{
			_b2World = new b2World(new b2Vec2(0,10), true);
			_b2World.SetContactListener(new B2CollistionListener(_b2World));
		}
		
		public function start():void
		{
			_interval = new IntervalCallBack();
			_interval.callbackFunc = onFrame;
			_interval.start();
		}
		
		private function onFrame(param:*):void
		{
			_b2World.Step(1/30, 10, 10);
			_b2World.ClearForces();
			
			var body:b2Body;
			for(body=_b2World.GetBodyList(); body; body=body.GetNext())
			{
				var boxItem:BoxItem = body.GetUserData() as BoxItem;
				if(boxItem)
				{
					var itemStat:int = boxItem.itemStat;
					switch(itemStat)
					{
						case Box2dDefine.BOX_ITEM_DATA_REMOVE:
							_b2World.DestroyBody(body);
							break;
						case Box2dDefine.BOX_ITEM_DATA_WORLD2GAME:
							var itemPosX:Number = body.GetPosition().x*Box2dDefine.PIXEL_PER_METER%GlobalInfo.fullWidth;
							var itemPosY:Number = body.GetPosition().y*Box2dDefine.PIXEL_PER_METER;
							boxItem.boxBody.SetPosition(new b2Vec2(itemPosX/Box2dDefine.PIXEL_PER_METER, itemPosY/Box2dDefine.PIXEL_PER_METER));
							
							boxItem.viewObj.x = body.GetPosition().x*Box2dDefine.PIXEL_PER_METER;
							boxItem.viewObj.y = body.GetPosition().y*Box2dDefine.PIXEL_PER_METER;
							boxItem.viewObj.rotation = body.GetAngle()*180/Math.PI;
							break;
						case Box2dDefine.BOX_ITEM_DATA_GAME2WORLD:
							if(boxItem.viewObj)
							{
								boxItem.boxBody.SetPosition(new b2Vec2(boxItem.viewObj.x/Box2dDefine.PIXEL_PER_METER, boxItem.viewObj.y/Box2dDefine.PIXEL_PER_METER));
							}
							break;
					}
				}
			}
			
			_b2World.DrawDebugData();
		}
		
		public function createB2ItemArr(b2ItemArr:Array):void
		{
			if(!b2ItemArr)
			{
				return;
			}
			
			var b2Item:BoxItem;
			var i:int;
			for(i=0; i<b2ItemArr.length; i++)
			{
				b2Item = b2ItemArr[i] as BoxItem;
				if(b2Item)
				{
					createB2Item(b2Item);
				}
			}
		}
		
		public function createB2Item(b2Item:BoxItem):void
		{
			if(!b2Item)
			{
				return;
			}
			var bodydef:b2BodyDef = new b2BodyDef();
			bodydef.position.Set(b2Item.bX/Box2dDefine.PIXEL_PER_METER, b2Item.bY/Box2dDefine.PIXEL_PER_METER);
			bodydef.type = b2Item.b2Type;
			
			var fixtureDef:b2FixtureDef = new b2FixtureDef();
			fixtureDef.density  = b2Item.density;
			fixtureDef.friction = b2Item.friction;
			fixtureDef.restitution = b2Item.restitution;
			fixtureDef.isSensor = b2Item.isSensor;
			
			var boxShap:b2PolygonShape = new b2PolygonShape();
			boxShap.SetAsBox(b2Item.bW/2/Box2dDefine.PIXEL_PER_METER, b2Item.bH/2/Box2dDefine.PIXEL_PER_METER);
			var body:b2Body = _b2World.CreateBody(bodydef);
			fixtureDef.shape = boxShap;
			body.CreateFixture(fixtureDef);
			body.SetUserData(b2Item);
			body.SetAngle(b2Item.angle);
			b2Item.boxBody = body;
		}
		
		public function destroyB2World():void
		{
			clearWorld();
			//_b2World = null;
		}
		
		public function clearWorld():void
		{
			if(_interval)
			{
				_interval.stop();
				_interval = null;
			}
			
			if(!_b2World)
			{
				return;
			}
			
			var body:b2Body = _b2World.GetBodyList();
			while(body)
			{
				_b2World.DestroyBody(body);
				body = _b2World.GetBodyList();
			}
		}
		
		public function createDebugDraw():Sprite
		{
			var debugDraw:b2DebugDraw = new b2DebugDraw();
			var sp:Sprite = new Sprite();
			sp.mouseChildren = false;
			sp.mouseEnabled  = false;
			debugDraw.SetSprite(sp);
			debugDraw.SetDrawScale(Box2dDefine.PIXEL_PER_METER);
			debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
			debugDraw.SetFillAlpha(0.3);
			_b2World.SetDebugDraw(debugDraw);
			return sp;
		}
	}
}